package com.moji.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.moji.common.base.ApiResult;
import com.moji.common.entity.MyPage;
import com.moji.common.utils.PageUtil;
import com.moji.entity.*;
import com.moji.entity.dto.*;
import com.moji.entity.vo.MjUserVo;
import com.moji.mapper.MjCompanyInfoMapper;
import com.moji.mapper.MjUserMapper;
import com.moji.service.GdAreaService;
import com.moji.service.MjOrderDetailService;
import com.moji.service.MjOrderService;
import com.moji.service.MjUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moji.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 客户信息表 服务实现类
 * </p>
 *
 * @author ccl
 * @since 2024-08-17
 */
@Service
public class MjUserServiceImpl extends ServiceImpl<MjUserMapper, MjUser> implements MjUserService {

    @Resource
    private MjCompanyInfoMapper mjCompanyInfoMapper;

    @Resource
    private MjOrderDetailService mjOrderDetailService;

    @Resource
    private GdAreaService gdAreaService;

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Resource
    private IdGenerator idGenerator;

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public MyPage<MjUserVo> queryByPage(QueryUserDto dto) {
        List<MjUserVo> mjUserVoList=new ArrayList<>();
        LambdaQueryWrapper<MjUser> wrapper = new LambdaQueryWrapper<>();
        //创建时间倒叙
        wrapper.orderByDesc(MjUser::getCreateTime);
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<MjUser> mjUserList = list(wrapper);
        if(ObjectUtil.isNotEmpty(mjUserList)){
            mjUserList.forEach(user->{
                MjUserVo mjUserVo=new MjUserVo();
                BeanUtils.copyProperties(user,mjUserVo);

                MjCompanyInfo mjCompanyInfo=mjCompanyInfoMapper.selectOne(new LambdaQueryWrapper<MjCompanyInfo>()
                        .eq(MjCompanyInfo::getCompanyCode,user.getCompanyCode()));
                BeanUtils.copyProperties(mjCompanyInfo,mjUserVo);

                mjUserVoList.add(mjUserVo);
            });
        }

        PageInfo<MjUserVo> info = new PageInfo<>(mjUserVoList);
        return PageUtil.PageInfo2MyPage(info);
    }

    @Override
    public boolean delete(Long id) {
        if(ObjectUtil.isEmpty(id)){
            throw new RuntimeException("主键ID不能为空,请核查!");
        }
        return this.removeById(id);
    }

    @Override
    public RespLoginDto add(AddMjUserDto dto) {
        MjUser mjUserOld = this.getOne(new LambdaQueryWrapper<MjUser>()
                .eq(MjUser::getMobile, dto.getMobile()));
        if (mjUserOld != null) {
            throw new RuntimeException("用户已存在,请核查!");
        }
        //姓名不能为空
        if (dto.getUserType()==0&&StringUtils.isEmpty(dto.getUserName())) {
            throw new RuntimeException("用户姓名不能为空,请核查!");
        }
        //校验手机号码合法性
        if (StringUtils.isNotEmpty(dto.getMobile()) && !CheckUtils.isPhoneLegal(dto.getMobile())) {
            throw new RuntimeException("手机号码格式不合法,请核查!");
        }
        //校验邮箱合法性
        if (StringUtils.isNotEmpty(dto.getEmail()) && !CheckUtils.isEmailLegal(dto.getEmail())) {
            throw new RuntimeException("邮箱格式不合法,请核查!");
        }
        MjUser mjUser=new MjUser();
        BeanUtils.copyProperties(dto,mjUser);
        String code= idGenerator.idGenerator("KH");
        mjUser.setUserCode(code);
        mjUser.setLoginId(dto.getMobile());
        String md5Password = MD5Util.getMd5(dto.getPassword()).toUpperCase();
        mjUser.setPassword(md5Password);
        mjUser.setPrOnOff(ObjectUtil.isNotEmpty(mjUser.getPrOnOff())?mjUser.getPrOnOff():1);

        //用户类型 userType 0 - 个人用户 1 - 企业用户
        if(dto.getUserType()==1){
            if (StringUtils.isEmpty(dto.getCompanyName())) {
                throw new RuntimeException("企业名称不能为空,请核查!");
            }
            if (StringUtils.isEmpty(dto.getSocietyCreditCode())) {
                throw new RuntimeException("统一社会信用代码不能为空,请核查!");
            }
            //自定义生成企业编码
            String companyCode= idGenerator.idGenerator("QY");
            MjCompanyInfo mjCompanyInfo=new MjCompanyInfo();
            BeanUtils.copyProperties(dto,mjCompanyInfo);
            mjCompanyInfo.setCompanyCode(companyCode);
            mjCompanyInfo.setCreateTime(new Date());
            mjCompanyInfo.setUpdateTime(new Date());
            mjCompanyInfo.setUpdateId(MoJiCommonUtils.getUserCode());
            mjCompanyInfo.setCreateId(MoJiCommonUtils.getUserCode());
            mjCompanyInfoMapper.insert(mjCompanyInfo);

            mjUser.setCompanyCode(companyCode);
            mjUser.setCompanyName(mjCompanyInfo.getCompanyName());
        }
        mjUser.setCreateId(MoJiCommonUtils.getUserCode());
        mjUser.setUpdateId(MoJiCommonUtils.getUserCode());
        mjUser.setCreateTime(new Date());
        mjUser.setUpdateTime(new Date());
        this.save(mjUser);

        //jwt生成token
        UserInfo userInfo = new UserInfo();
        userInfo.setLoginId(mjUser.getLoginId());
        userInfo.setUserCode(mjUser.getUserCode());
        userInfo.setUserName(mjUser.getUserName());
        userInfo.setDeptCode(mjUser.getDeptCode());
        userInfo.setMobile(mjUser.getMobile());
        userInfo.setRoleCode(mjUser.getRolesCode());
        String token = jwtTokenUtil.createToken(userInfo);
        //放入redis缓存
//        if(redisTemplate.hasKey(token)){
//            redisTemplate.delete(token);
//            redisTemplate.opsForValue().set(token,token, Integer.valueOf(MdsEnumConfig.CCP_SYSTEM_TOKEN_TIME.getCode()), TimeUnit.MINUTES);
//        }else{
//            redisTemplate.opsForValue().set(token,token, Integer.valueOf(MdsEnumConfig.CCP_SYSTEM_TOKEN_TIME.getCode()), TimeUnit.MINUTES);
//        }

        //返给前端登录人基本信息和权限
        RespLoginDto respDao = new RespLoginDto();
        BeanUtils.copyProperties(mjUser,respDao);
        respDao.setAuthorization(token);
        return respDao;
    }

    @Override
    public boolean edit(AddMjUserDto dto) {
        //姓名不能为空
        if (StringUtils.isEmpty(dto.getUserName())) {
            throw new RuntimeException("用户姓名不能为空,请核查!");
        }
        //校验手机号码合法性
        if (StringUtils.isNotEmpty(dto.getMobile()) && !CheckUtils.isPhoneLegal(dto.getMobile())) {
            throw new RuntimeException("手机号码格式不合法,请核查!");
        }
        //校验邮箱合法性
        if (StringUtils.isNotEmpty(dto.getEmail()) && !CheckUtils.isEmailLegal(dto.getEmail())) {
            throw new RuntimeException("邮箱格式不合法,请核查!");
        }
        MjUser mjUser=this.getById(dto.getId());
        BeanUtils.copyProperties(dto,mjUser);
        mjUser.setUpdateTime(new Date());
        mjUser.setUpdateId(MoJiCommonUtils.getUserCode());
        //用户类型 userType 0 - 个人用户 1 - 企业用户
        if(dto.getUserType()==1){
            MjCompanyInfo mjCompanyInfo=mjCompanyInfoMapper.selectOne(new LambdaQueryWrapper<MjCompanyInfo>()
                    .eq(MjCompanyInfo::getCompanyCode,dto.getCompanyCode()));
            Long id=mjCompanyInfo.getId();
            BeanUtils.copyProperties(dto,mjCompanyInfo);
            mjCompanyInfo.setId(id);
            mjCompanyInfo.setUpdateTime(new Date());
            mjCompanyInfo.setUpdateId(MoJiCommonUtils.getUserCode());
            mjCompanyInfoMapper.updateById(mjCompanyInfo);
        }
        return this.updateById(mjUser);
    }

    @Override
    public MjUserVo detail(Long id) {
        if(ObjectUtil.isEmpty(id)){
            throw new RuntimeException("主键ID不能为空,请核查!");
        }
        MjUserVo mjUserVo=new MjUserVo();
        //个人信息
        MjUser mjUser=this.getById(id);
        BeanUtils.copyProperties(mjUser,mjUserVo);
//        MjOrderDetailmjOrderDetailService.getOne(new LambdaQueryWrapper<MjOrderDetail>()
//                .eq(MjOrderDetail::getCreateId,mjUser.getUserCode()));
//        if(){
//
//        }
        //企业信息
        MjCompanyInfo mjCompanyInfo=mjCompanyInfoMapper.selectOne(new LambdaQueryWrapper<MjCompanyInfo>()
                .eq(MjCompanyInfo::getCompanyCode,mjUser.getCompanyCode()));
        if(mjCompanyInfo != null){
            BeanUtils.copyProperties(mjCompanyInfo,mjUserVo);
            String companyAddress = mjCompanyInfo.getCompanyAddress();
            StringBuilder stringBuilder=new StringBuilder();
            if(companyAddress.split(",")!=null&&companyAddress.split(",").length>0)
            {
                String[] split = companyAddress.split(",");

                for (int i = 0; i < split.length; i++) {
                    LambdaQueryWrapper<GdArea> wrapper1 = new LambdaQueryWrapper<>();
                    wrapper1.eq(GdArea::getAreaCode,split[i]);
                    String areaName = gdAreaService.getOne(wrapper1).getAreaName();
                    stringBuilder.append(areaName);
                }
                mjUserVo.setCompanyAddressName(stringBuilder.toString());
            }
        }
        mjUserVo.setId(mjUser.getId());
        return mjUserVo;
    }

    @Override
    public boolean resetPassword(ResetPasswordDto dto) {
        MjUser mjUser = this.getOne(new LambdaQueryWrapper<MjUser>()
                .eq(MjUser::getMobile,dto.getMobile()));
        if (mjUser == null) {
            throw new RuntimeException("用户不存在,请核查!");
        }
        mjUser.setPassword(MD5Util.getMd5(dto.getPassword()).toUpperCase());
        return this.updateById(mjUser);
    }

    @Override
    public boolean modifyPassword(ModifyPasswordDto modifyPasswordDao) {
        String newPassword = modifyPasswordDao.getNewPassword();
        String oldPassword = modifyPasswordDao.getOldPassword();
        String md5NewPassword = MD5Util.getMd5(newPassword).toUpperCase();
        //String md5OldPassword = MD5Util.getMd5(oldPassword).toUpperCase();
        LambdaQueryWrapper<MjUser> wrapper = new LambdaQueryWrapper();
        wrapper.eq(MjUser::getLoginId, modifyPasswordDao.getLoginId());
        MjUser mjUser = this.getOne(wrapper);
        if (mjUser == null) {
            throw new RuntimeException("用户不存在,请核查!");
        }
        //if (mjUser.getPassword().equals(md5OldPassword)) {
            mjUser.setPassword(md5NewPassword);
        //}
        return this.updateById(mjUser);
    }

    @Override
    public RespLoginDto login(ReqLoginDto loginReqDao) {
        String loginId = loginReqDao.getLoginId();
        String password = loginReqDao.getPassword();
        //校验登陆账号不为空
        if(StringUtils.isEmpty(loginId)){
            throw new RuntimeException("登录账号不能为空,请核查!");
        }
        //校验登陆密码不为空 登录类型 0 - 账号登录 1 - 验证码登录
        if(0==loginReqDao.getLoginType() && StringUtils.isEmpty(password)){
            throw new RuntimeException("登录密码不能为空,请核查!");
        }
        LambdaQueryWrapper<MjUser> wrapper = new LambdaQueryWrapper();
        wrapper.eq(MjUser::getLoginId,loginReqDao.getLoginId());
        MjUser mjUser = this.getOne(wrapper);
        if(mjUser == null){
            throw new RuntimeException("登录账号或手机号错误,请核查!");
        }
//        if(redisTemplate.hasKey(loginReqDao.getGraphicCode())){
//           if(!redisTemplate.opsForValue().get(loginReqDao.getGraphicCode()).equals(loginReqDao.getGraphicCode())){
//               throw new RuntimeException("图形验证码错误,请核查!");
//           }
//        }
        if(0==loginReqDao.getLoginType()){
            String md5Password = MD5Util.getMd5(password).toUpperCase();
            if(!md5Password.equals(mjUser.getPassword())){
                throw new RuntimeException("登录密码错误,请核查!");
            }
        }
        if(1==loginReqDao.getLoginType()){
            //短信验证码
            String phoneCode = loginReqDao.getPhoneCode();
            if(!phoneCode.equals("1234")){
                throw new RuntimeException("短信验证码错误,请核查!");
            }
        }

        //记录登陆时间
        mjUser.setLastLoginTime(mjUser.getNewLoginTime());
        mjUser.setNewLoginTime(new Date());
        this.updateById(mjUser);
        //jwt生成token
        UserInfo userInfo = new UserInfo();
        userInfo.setLoginId(mjUser.getLoginId());
        userInfo.setUserCode(mjUser.getUserCode());
        userInfo.setUserName(mjUser.getUserName());
        userInfo.setDeptCode(mjUser.getDeptCode());
        userInfo.setMobile(mjUser.getMobile());
        userInfo.setRoleCode(mjUser.getRolesCode());
        String token = jwtTokenUtil.createToken(userInfo);
        //放入redis缓存
//        if(redisTemplate.hasKey(token)){
//            redisTemplate.delete(token);
//            redisTemplate.opsForValue().set(token,token, Integer.valueOf(MdsEnumConfig.CCP_SYSTEM_TOKEN_TIME.getCode()), TimeUnit.MINUTES);
//        }else{
//            redisTemplate.opsForValue().set(token,token, Integer.valueOf(MdsEnumConfig.CCP_SYSTEM_TOKEN_TIME.getCode()), TimeUnit.MINUTES);
//        }

        //返给前端登录人基本信息和权限
        RespLoginDto respDao = new RespLoginDto();
        BeanUtils.copyProperties(mjUser,respDao);
        respDao.setAuthorization(token);
        return respDao;
    }

    @Override
    public void logout(String loginId, HttpServletRequest request) {
        String token = request.getHeader("authorization");
        if(redisTemplate.hasKey(token)){
            redisTemplate.delete(token);
        }
    }

    @Override
    public boolean editPassword(ModifyPasswordDto modifyPasswordDao) {
        String newPassword = modifyPasswordDao.getNewPassword();
        String oldPassword = modifyPasswordDao.getOldPassword();
        String md5NewPassword = MD5Util.getMd5(newPassword).toUpperCase();
        String md5OldPassword = MD5Util.getMd5(oldPassword).toUpperCase();
        LambdaQueryWrapper<MjUser> wrapper = new LambdaQueryWrapper();
        wrapper.eq(MjUser::getUserCode, modifyPasswordDao.getUserCode());
        MjUser mjUser = this.getOne(wrapper);
        if (mjUser == null) {
            throw new RuntimeException("用户不存在,请核查!");
        }
        if (mjUser.getPassword().equals(md5OldPassword)) {
            mjUser.setPassword(md5NewPassword);
        }
        return this.updateById(mjUser);
    }

}
